package org.dinnermate.log;

public class LogRecord
{
	private Level level;
	private String msg;
	private long time;
	private String sourceClassName;
	private String sourceMethodName;
	private Throwable thrown;
	private boolean needToInferCaller;

	public LogRecord( Level level, String msg )
	{
		level.getClass(); // make sure it's not null
		this.level = level;
		this.msg = msg;
		time = System.currentTimeMillis();
		needToInferCaller = true;
	}

	public Level getLevel()
	{
		return level;
	}

	public void setLevel( Level level )
	{
		this.level = level;
	}

	public String getMessage()
	{
		return msg;
	}

	public void setMessage( String msg )
	{
		this.msg = msg;
	}
	
	public long getTime()
	{
		return time;
	}
	
	public void setTime(long time)
	{
		this.time = time;
	}

	public String getSourceClassName()
	{
		if (needToInferCaller) inferCaller();
		return sourceClassName;
	}

	public void setSourceClassName( String sourceClassName )
	{
		this.sourceClassName = sourceClassName;
		needToInferCaller = false;
	}

	public String getSourceMethodName()
	{
		if (needToInferCaller) inferCaller();
		return sourceMethodName;
	}

	public void setSourceMethodName( String sourceMethodName )
	{
		this.sourceMethodName = sourceMethodName;
		needToInferCaller = false;
	}
	
	public Throwable getThrown()
	{
		return thrown;
	}
	
	public void setThrown(Throwable thrown)
	{
		this.thrown = thrown;
	}
	
	// Private method to infer the caller's class and method names
    private void inferCaller() {
        needToInferCaller = false;
        // Get the stack trace.
        StackTraceElement stack[] = (new Throwable()).getStackTrace();
        // First, search back to a method in the Logger class.
        int ix = 0;
        while (ix < stack.length) {
            StackTraceElement frame = stack[ix];
            String cname = frame.getClassName();
            if (cname.equals("java.util.logging.Logger")) {
                break;
            }
            ix++;
        }
        // Now search for the first frame before the "Logger" class.
        while (ix < stack.length) {
            StackTraceElement frame = stack[ix];
            String cname = frame.getClassName();
            if (!cname.equals("java.util.logging.Logger")) {
                // We've found the relevant frame.
                setSourceClassName(cname);
                setSourceMethodName(frame.getMethodName());
                return;
            }
            ix++;
        }
        // We haven't found a suitable frame, so just punt.  This is
        // OK as we are only committed to making a "best effort" here.
    }
}
